package com.apes.framework.jpa;

import com.apes.framework.api.SpringManager;
//import com.apes.framework.jpa.extend.DynamicExtendTable;
//import com.apes.framework.jpa.extend.DynamicExtendTableRepository;
import com.apes.framework.plugin.event.EventConst;
import com.apes.framework.plugin.event.EventService;
import com.apes.framework.jpa.tuple.date.DateTime;
import com.apes.framework.util.ReflectUtil;
import org.hibernate.annotations.GenerationTime;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.persistence.*;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Date;


/**
 * 功能：实体生命周期事件监听器（DefaultPersistEventListener）
 * <p>
 * 使用时在实体上加上注解： @EntityListeners(DefaultPersistListener.class)
 *
 * @author xul
 * @create 2018-03-28 16:53
 */
@Component
public class DefaultPersistListener {

    /**
     * 功能：插入前事件
     */
    @PrePersist
    public void prePersist(Object entity) {
        send(EventConst.PRE_PERSIST_EVENT, entity);
    }

    /**
     * 功能：插入后事件
     */
    @PostPersist
    public void postPersist(Object entity) {
        if (entity instanceof BaseModel) {
            ((BaseModel) entity).setWrite(true);
            ((BaseModel) entity).setAction("add");
        }
        send(EventConst.POST_PERSIST_EVENT, entity);
    }

    private void saveExtendTable(BaseModel entity) {
//        String businessType = entity.getClass().getSimpleName();
//        String businessKey = JpaUtil.getIdToStr(entity);
//        DynamicExtendTableRepository tableRepository = SpringManager.getBean(DynamicExtendTableRepository.class);
//        DynamicExtendTable extendTable = tableRepository.findFirstByBusinessTypeAndBusinessKey(businessType, businessKey);
//        if (extendTable == null) {
//            extendTable = new DynamicExtendTable();
//            extendTable.setId(12);
//            extendTable.setBusinessType(businessType);
//            extendTable.setBusinessKey(businessKey);
//        }
//        extendTable.setExtProperties(entity.extProperties);
//        extendTable.serialize();
//        tableRepository.save(extendTable);
    }

    /**
     * 功能：修改前事件
     */
    @PreUpdate
    public void preUpdate(Object entity) {
        if (entity == null) return;
        if (!ApesBean.class.isAssignableFrom(entity.getClass())) return;
        if (ReflectUtil.getAnnotation(entity.getClass(), Entity.class) == null) return;
        PropertyDescriptor[] propertyDescriptors = ReflectUtil.getPropertyDescriptors(entity);
        if (propertyDescriptors == null) return;
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            DateTime annotation = ReflectUtil.getAnnotation(entity, descriptor.getName(), DateTime.class);
            if (annotation != null && annotation.value() == GenerationTime.ALWAYS) {
                try {
                    Method writer = descriptor.getWriteMethod();
                    writer.invoke(entity, new Date());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        send(EventConst.PRE_UPDATE_EVENT, entity);
    }

    /**
     * 功能：修改后事件
     */
    @PostUpdate
    public void postUpdate(Object entity) {
        if (entity instanceof BaseModel) {
            ((BaseModel) entity).setWrite(true);
            ((BaseModel) entity).setAction("update");
        }
        send(EventConst.POST_UPDATE_EVENT, entity);
    }

    /**
     * 功能：删除前事件
     */
    @PreRemove
    public void preRemove(Object entity) {
        if (entity instanceof BaseModel) {
            ((BaseModel) entity).setAction("remove");
        }
        send(EventConst.PRE_REMOVE_EVENT, entity);
    }

    /**
     * 功能：删除后事件
     */
    @PostRemove
    public void postRemove(Object entity) {
        if (entity instanceof BaseModel) ((BaseModel) entity).setWrite(true);
        send(EventConst.POST_REMOVE_EVENT, entity);
    }

    /**
     * 功能：查询后事件
     */
    @PostLoad
    public void postLoad(Object entity) {
//        if(entity instanceof BaseModel){
//            ((BaseModel) entity).deserializeProperties();
//        }
        if (entity instanceof BaseModel) ((BaseModel) entity).setLoad(true);
        send(EventConst.POST_LOAD_EVENT, entity);
    }

    /**
     *  getTopic(PRE_PERSIST_EVENT, entity.getClass().getSimpleName())
     */
    private String getTopic(String prefix, String suffix) {
        String topic = prefix;
        if (!StringUtils.isEmpty(suffix)) topic = topic + "." + suffix;
        return topic;
    }

    private void send(String topic, Object entity) {
        SpringManager.getBean(EventService.class).sendSynEvent(topic, entity);
    }

}
